<?php

namespace Soen\Container\Aop;

use PhpParser\Parser;
use PhpParser\NodeTraverser;
use PhpParser\ParserFactory;
use PhpParser\PrettyPrinter\Standard;

class Aop
{
    /**
     * @var Parser
     */
    public $parser;
    public $className;
    function __construct(string $className)
    {
        $this->createParser();
        $this->className = $className;
    }

    /**
     * 根据明明空间获取 文件源代码
     * @param string $className
     * @return false|string
     * @throws \ReflectionException
     */
    public function getFileCodeByClass(string $className){
        $reflection = new \ReflectionClass($className);
        return file_get_contents($reflection->getFileName());
    }

    /**
     * 创建 php文件解析器
     * @return \PhpParser\Parser
     */
    public function createParser(){
        $this->parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
        return $this->parser;
    }

    public function parse($code){
        return $this->parser->parse($code);
    }

    public function setPropertys(array $propertys){
        $setting = [
            'propertys' => $propertys
        ];
        $visitor = new ProxyVisitor($this->className, uniqid(), $setting);
        $traverser = new NodeTraverser;
        $traverser->addVisitor($visitor);
        $ast = $this->parse($this->getFileCodeByClass($this->className));
        $proxyAst = $traverser->traverse($ast);
        $printer = new Standard();
        $proxyCode = $printer->prettyPrint($proxyAst);
        $classPathName = $visitor->getClassName();
//        var_dump($proxyCode);
        eval($proxyCode);
        return $classPathName;
//        $classPathNameArr = explode('\\', $classPathName);
//        $className = end($classPathNameArr);

//        $str = <<<eof
//<?php
//declare (strict_types=1);
//eof;
//        $proxyCode = $str.$proxyCode;
//        var_dump($proxyCode);

//        $classFileName = $className . '.php';
//        file_put_contents(BASE_PATH . '/runtime/container/parser/' . $classFileName, $proxyCode);
//        return $classPathName;
    }
    
    
    public function getPropertys(){
        
    }
}